home *** CD-ROM | disk | FTP | other *** search
- Subject: v11i080: C cross-reference database system, Part03/03
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rs@uunet.UU.NET
-
- Submitted-by: sun!suneast!kumquat!gmcgary (Greg Mcgary - Sun ECD Software)
- Posting-number: Volume 11, Issue 80
- Archive-name: id/Part03
-
-
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # mkid.c
- # numtst.c
- # opensrc.c
- # paths.c
- # scan-asm.c
- # scan-c.c
- # stoi.c
- # tty.c
- # uerror.c
- # wmatch.c
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'mkid.c'" '(17095 characters)'
- sed 's/^X//' << \SHAR_EOF > 'mkid.c'
- Xstatic char copyright[] = "@(#)Copyright (c) 1986, Greg McGary";
- Xstatic char sccsid[] = "@(#)mkid.c 1.4 86/11/06";
- X
- X#include <bool.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <stdio.h>
- X#include <string.h>
- X#include <ctype.h>
- X#include <id.h>
- X#include <bitops.h>
- X#include <errno.h>
- X#include <extern.h>
- X
- Xint idnHashCmp();
- Xint idnQsortCmp();
- Xint round2();
- Xstruct idname *newIdName();
- Xvoid extractId();
- Xvoid fileIdArgs();
- Xvoid initHashTable();
- Xvoid oldIdArgs();
- Xvoid rehash();
- Xvoid updateID();
- Xvoid writeID();
- X
- Xlong NameCount; /* Count of names in database */
- Xlong NumberCount; /* Count of numbers in database */
- Xlong StringCount; /* Count of strings in database */
- Xlong SoloCount; /* Count of identifiers that occur only once */
- X
- Xlong HashSize; /* Total Slots in hash table */
- Xlong HashMaxLoad; /* Maximum loading of hash table */
- Xlong HashFill; /* Number of keys inserted in table */
- Xlong HashProbes; /* Total number of probes */
- Xlong HashSearches; /* Total number of searches */
- Xstruct idname **HashTable; /* Vector of idname pointers */
- X
- Xbool Verbose = FALSE;
- X
- Xint ArgsCount = 0; /* Count of args to save */
- Xint ScanCount = 0; /* Count of files to scan */
- Xint PathCount = 0; /* Count of files covered in database */
- Xint BitArraySize; /* Size of bit array slice (per name) */
- X
- X
- Xchar *MyName;
- Xstatic void
- Xusage()
- X{
- X fprintf(stderr, "Usage: %s [-f<idfile>] [-s<dir>] [-r<dir>] [(+|-)l[<lang>]] [-v] [(+|-)S<scanarg>] [-a<argfile>] [-] [-u] [files...]\n", MyName);
- X exit(1);
- X}
- Xmain(argc, argv)
- X int argc;
- X char **argv;
- X{
- X char *arg;
- X int op;
- X FILE *argFILE = NULL;
- X char *idFile = IDFILE;
- X char *rcsDir = NULL;
- X char *sccsDir = NULL;
- X struct idarg *idArgs, *idArgHead;
- X bool keepLang = FALSE;
- X int argsFrom = 0;
- X#define AF_CMDLINE 0x1 /* file args came on command line */
- X#define AF_FILE 0x2 /* file args came from a file (-f<file>) */
- X#define AF_IDFILE 0x4 /* file args came from an old ID file (-u) */
- X#define AF_QUERY 0x8 /* no file args necessary: usage query */
- X
- X MyName = basename(GETARG(argc, argv));
- X#ifdef ERRLINEBUF
- X setlinebuf(stderr);
- X#endif
- X
- X idArgs = idArgHead = NEW(struct idarg);
- X
- X /*
- X Process some arguments, and snarf-up some
- X others for processing later.
- X */
- X while (argc) {
- X arg = GETARG(argc, argv);
- X if (*arg != '-' && *arg != '+') {
- X argsFrom |= AF_CMDLINE;
- X idArgs->ida_arg = arg;
- X idArgs->ida_flags = IDA_SCAN|IDA_PATH;
- X idArgs->ida_index = postIncr(&PathCount);
- X ScanCount++;
- X idArgs = (idArgs->ida_next = NEW(struct idarg));
- X continue;
- X }
- X op = *arg++;
- X switch (*arg++)
- X {
- X case 'u':
- X argsFrom |= AF_IDFILE;
- X oldIdArgs(idFile, &idArgs);
- X break;
- X case '\0':
- X argsFrom |= AF_FILE;
- X fileIdArgs(stdin, &idArgs);
- X break;
- X case 'a':
- X if ((argFILE = fopen(arg, "r")) == NULL) {
- X filerr("open", arg);
- X exit(1);
- X }
- X argsFrom |= AF_FILE;
- X fileIdArgs(argFILE, &idArgs);
- X break;
- X case 'f':
- X idFile = arg;
- X break;
- X case 'v':
- X Verbose = TRUE;
- X break;
- X case 'S':
- X if (strchr(&arg[-2], '?')) {
- X setScanArgs(op, arg);
- X argsFrom |= AF_QUERY;
- X }
- X /*FALLTHROUGH*/
- X case 'l':
- X case 's':
- X case 'r':
- X idArgs->ida_arg = &arg[-2];
- X idArgs->ida_index = -1;
- X idArgs->ida_flags = IDA_ARG;
- X idArgs = (idArgs->ida_next = NEW(struct idarg));
- X ArgsCount++;
- X break;
- X default:
- X usage();
- X }
- X }
- X
- X if (argsFrom & AF_QUERY)
- X exit(0);
- X /*
- X File args should only come from one place. Ding the
- X user if arguments came from multiple places, or if none
- X were supplied at all.
- X */
- X switch (argsFrom)
- X {
- X case AF_CMDLINE:
- X case AF_FILE:
- X case AF_IDFILE:
- X if (PathCount > 0)
- X break;
- X /*FALLTHROUGH*/
- X case 0:
- X fprintf(stderr, "%s: Use -u, -f<file>, or cmd-line for file args!\n", MyName);
- X usage();
- X default:
- X fprintf(stderr, "%s: Use only one of: -u, -f<file>, or cmd-line for file args!\n", MyName);
- X usage();
- X }
- X
- X if (ScanCount == 0)
- X exit(0);
- X
- X BitArraySize = (PathCount + 7) >> 3;
- X initHashTable(ScanCount);
- X
- X if (access(idFile, 06) < 0
- X && (errno != ENOENT || access(dirname(idFile), 06) < 0)) {
- X filerr("modify", idFile);
- X exit(1);
- X }
- X
- X for (idArgs = idArgHead; idArgs->ida_next; idArgs = idArgs->ida_next) {
- X char *(*scanner)();
- X FILE *srcFILE;
- X char *arg, *lang, *suff;
- X
- X arg = idArgs->ida_arg;
- X if (idArgs->ida_flags & IDA_ARG) {
- X op = *arg++;
- X switch (*arg++)
- X {
- X case 'l':
- X if (*arg == '\0') {
- X keepLang = FALSE;
- X lang = NULL;
- X break;
- X }
- X if (op == '+')
- X keepLang = TRUE;
- X lang = arg;
- X break;
- X case 's':
- X sccsDir = arg;
- X break;
- X case 'r':
- X rcsDir = arg;
- X break;
- X case 'S':
- X setScanArgs(op, strsav(arg));
- X break;
- X default:
- X usage();
- X }
- X continue;
- X }
- X if (!(idArgs->ida_flags & IDA_SCAN))
- X goto skip;
- X if (lang == NULL) {
- X if ((suff = strrchr(arg, '.')) == NULL)
- X suff = "";
- X if ((lang = getLanguage(suff)) == NULL) {
- X fprintf(stderr, "%s: No language assigned to suffix: `%s'\n", MyName, suff);
- X goto skip;
- X }
- X }
- X if ((scanner = getScanner(lang)) == NULL) {
- X fprintf(stderr, "%s: No scanner for language: `%s'\n", MyName, lang);
- X goto skip;
- X }
- X if ((srcFILE = openSrcFILE(arg, sccsDir, rcsDir)) == NULL)
- X goto skip;
- X if (Verbose)
- X fprintf(stderr, "%s: %s\n", lang, arg);
- X extractId(scanner, srcFILE, idArgs->ida_index);
- X fclose(srcFILE);
- X skip:
- X if (!keepLang)
- X lang = NULL;
- X }
- X
- X if (HashFill == 0)
- X exit(0);
- X
- X if (Verbose)
- X fprintf(stderr, "Compressing Hash Table...\n");
- X hashCompress(HashTable, HashSize);
- X if (Verbose)
- X fprintf(stderr, "Sorting Hash Table...\n");
- X qsort(HashTable, HashFill, sizeof(struct idname *), idnQsortCmp);
- X
- X if (argsFrom == AF_IDFILE) {
- X if (Verbose)
- X fprintf(stderr, "Merging Tables...\n");
- X updateID(idFile, idArgHead);
- X }
- X
- X if (Verbose)
- X fprintf(stderr, "Writing `%s'...\n", idFile);
- X writeID(idFile, idArgHead);
- X
- X if (Verbose) {
- X float loadFactor = (float)HashFill / (float)HashSize;
- X float aveProbes = (float)HashProbes / (float)HashSearches;
- X float aveOccur = (float)HashSearches / (float)HashFill;
- X fprintf(stderr, "Names: %ld, ", NameCount);
- X fprintf(stderr, "Numbers: %ld, ", NumberCount);
- X fprintf(stderr, "Strings: %ld, ", StringCount);
- X fprintf(stderr, "Solo: %ld, ", SoloCount);
- X fprintf(stderr, "Total: %ld\n", HashFill);
- X fprintf(stderr, "Occurances: %.2f, ", aveOccur);
- X fprintf(stderr, "Load: %.2f, ", loadFactor);
- X fprintf(stderr, "Probes: %.2f\n", aveProbes);
- X }
- X exit(0);
- X}
- X
- Xvoid
- XextractId(getId, srcFILE, index)
- X register char *(*getId)();
- X register FILE *srcFILE;
- X int index;
- X{
- X register struct idname **slot;
- X register char *key;
- X int flags;
- X
- X while ((key = (*getId)(srcFILE, &flags)) != NULL) {
- X slot = (struct idname **)hashSearch(key, HashTable, HashSize, sizeof(struct idname *), h1str, h2str, idnHashCmp, &HashProbes);
- X HashSearches++;
- X if (*slot != NULL) {
- X (*slot)->idn_flags |= flags;
- X BITSET((*slot)->idn_bitv, index);
- X continue;
- X }
- X *slot = newIdName(key);
- X (*slot)->idn_flags = IDN_SOLO|flags;
- X BITSET((*slot)->idn_bitv, index);
- X if (HashFill++ >= HashMaxLoad)
- X rehash();
- X }
- X}
- X
- Xvoid
- XwriteID(idFile, idArgs)
- X char *idFile;
- X struct idarg *idArgs;
- X{
- X register struct idname **idnp;
- X register struct idname *idn;
- X register int i;
- X char *vecBuf;
- X FILE *idFILE;
- X int count;
- X int lasti;
- X long before, after;
- X int length, longest;
- X struct idhead idh;
- X
- X if ((idFILE = fopen(idFile, "w+")) == NULL) {
- X filerr("create", idFile);
- X exit(1);
- X }
- X fseek(idFILE, (long)sizeof(struct idhead), 0);
- X
- X /* write out the list of pathnames */
- X idh.idh_argo = ftell(idFILE);
- X for (i = lasti = 0; idArgs->ida_next; idArgs = idArgs->ida_next) {
- X if (idArgs->ida_index > 0)
- X while (++lasti < idArgs->ida_index)
- X i++, putc('\0', idFILE);
- X fputs(idArgs->ida_arg, idFILE);
- X i++, putc('\0', idFILE);
- X }
- X idh.idh_argc = i;
- X idh.idh_pthc = PathCount;
- X
- X /* write out the list of identifiers */
- X i = 1;
- X if (idh.idh_pthc >= 0x000000ff)
- X i++;
- X if (idh.idh_pthc >= 0x0000ffff)
- X i++;
- X if (idh.idh_pthc >= 0x00ffffff)
- X i++;
- X idh.idh_vecc = i;
- X
- X vecBuf = malloc((idh.idh_pthc + 1) * idh.idh_vecc);
- X
- X putc('\377', idFILE);
- X before = idh.idh_namo = ftell(idFILE);
- X longest = 0;
- X for (idnp = HashTable, i = 0; i < HashFill; i++, idnp++) {
- X idn = *idnp;
- X if (idn->idn_name[0] == '\0') {
- X HashFill--; i--;
- X continue;
- X }
- X if (idn->idn_flags & IDN_SOLO)
- X SoloCount++;
- X if (idn->idn_flags & IDN_NUMBER)
- X NumberCount++;
- X if (idn->idn_flags & IDN_NAME)
- X NameCount++;
- X if (idn->idn_flags & IDN_STRING)
- X StringCount++;
- X
- X putc((*idnp)->idn_flags, idFILE);
- X fputs(idn->idn_name, idFILE);
- X putc('\0', idFILE);
- X
- X count = bitsToVec(vecBuf, (*idnp)->idn_bitv, idh.idh_pthc, idh.idh_vecc);
- X fwrite(vecBuf, idh.idh_vecc, count, idFILE);
- X putc('\377', idFILE);
- X after = ftell(idFILE);
- X
- X if ((length = (after - before)) > longest)
- X longest = length;
- X before = after;
- X }
- X idh.idh_namc = i;
- X putc('\377', idFILE);
- X idh.idh_endo = ftell(idFILE);
- X idh.idh_bsiz = longest;
- X
- X /* write out the header */
- X strncpy(idh.idh_magic, IDH_MAGIC, sizeof(idh.idh_magic));
- X idh.idh_vers = IDH_VERS;
- X fseek(idFILE, 0L, 0);
- X fwrite(&idh, sizeof(struct idhead), 1, idFILE);
- X
- X fclose(idFILE);
- X}
- X
- X/*
- X Build an idarg vector from pathnames contained in an existing
- X id file. Only include pathnames for files whose modification
- X time is later than that of the id file itself.
- X*/
- Xvoid
- XoldIdArgs(idFile, idArgsP)
- X char *idFile;
- X struct idarg **idArgsP;
- X{
- X struct stat statBuf;
- X struct idhead idh;
- X FILE *idFILE;
- X register int i;
- X register char *strings;
- X time_t idModTime;
- X
- X if ((idFILE = fopen(idFile, "r")) == NULL) {
- X filerr("open", idFile);
- X usage();
- X }
- X /*
- X * Open the id file, get its mod-time, and read its header.
- X */
- X if (fstat(fileno(idFILE), &statBuf) < 0) {
- X filerr("stat", idFile);
- X usage();
- X }
- X idModTime = statBuf.st_mtime;
- X fread(&idh, sizeof(struct idhead), 1, idFILE);
- X if (!strnequ(idh.idh_magic, IDH_MAGIC, sizeof(idh.idh_magic))) {
- X fprintf(stderr, "%s: Not an id file: `%s'\n", MyName, idFile);
- X exit(1);
- X }
- X if (idh.idh_vers != IDH_VERS) {
- X fprintf(stderr, "%s: ID version mismatch (%ld,%ld)\n", MyName, idh.idh_vers, IDH_VERS);
- X exit(1);
- X }
- X
- X /*
- X * Read in the id pathnames, compare their mod-times with
- X * the id file, and incorporate the pathnames of recently modified
- X * files in the idarg vector. Also, construct a mask of
- X * bit array positions we want to turn off when we build the
- X * initial hash-table.
- X */
- X fseek(idFILE, idh.idh_argo, 0);
- X strings = malloc(i = idh.idh_namo - idh.idh_argo);
- X fread(strings, i, 1, idFILE);
- X ScanCount = 0;
- X for (i = 0; i < idh.idh_argc; i++) {
- X (*idArgsP)->ida_arg = strings;
- X if (*strings == '+' || *strings == '-') {
- X (*idArgsP)->ida_flags = IDA_ARG;
- X (*idArgsP)->ida_index = -1;
- X } else {
- X (*idArgsP)->ida_flags = IDA_PATH;
- X (*idArgsP)->ida_index = postIncr(&PathCount);
- X if (stat(strings, &statBuf) < 0) {
- X filerr("stat", strings);
- X } else if (statBuf.st_mtime >= idModTime) {
- X (*idArgsP)->ida_flags |= IDA_SCAN;
- X ScanCount++;
- X }
- X }
- X (*idArgsP) = ((*idArgsP)->ida_next = NEW(struct idarg));
- X while (*strings++)
- X ;
- X }
- X if (ScanCount == 0) {
- X fclose(idFILE);
- X exit(0);
- X }
- X fclose(idFILE);
- X}
- X
- Xvoid
- XupdateID(idFile, idArgs)
- X char *idFile;
- X struct idarg *idArgs;
- X{
- X struct idname *idn;
- X struct idhead idh;
- X register char *bitArray;
- X char *entry;
- X register int i;
- X FILE *idFILE;
- X int cmp, count, size;
- X char *bitsOff;
- X struct idname **newTable, **mergeTable;
- X struct idname **t1, **t2, **tm;
- X
- X if ((idFILE = fopen(idFile, "r")) == NULL)
- X filerr("open", idFile);
- X fread(&idh, sizeof(struct idhead), 1, idFILE);
- X
- X entry = malloc(idh.idh_bsiz);
- X
- X bitsOff = malloc(BitArraySize);
- X bzero(bitsOff, BitArraySize);
- X for (i = 0; idArgs->ida_next; idArgs = idArgs->ida_next)
- X if (idArgs->ida_flags & IDA_SCAN)
- X BITSET(bitsOff, idArgs->ida_index);
- X
- X bitArray = malloc(BitArraySize);
- X bzero(bitArray, BitArraySize);
- X t2 = newTable = (struct idname **)malloc((idh.idh_namc + 1) * sizeof(struct idname *));
- X fseek(idFILE, idh.idh_namo, 0);
- X count = 0;
- X for (i = 0; i < idh.idh_namc; i++) {
- X size = 1 + fgets0(entry, idh.idh_bsiz, idFILE);
- X getsFF(&entry[size], idFILE);
- X vecToBits(bitArray, &entry[size], idh.idh_vecc);
- X bitsclr(bitArray, bitsOff, BitArraySize);
- X if (!bitsany(bitArray, BitArraySize))
- X continue;
- X *t2 = newIdName(ID_STRING(entry));
- X bitsset((*t2)->idn_bitv, bitArray, BitArraySize);
- X (*t2)->idn_flags = ID_FLAGS(entry);
- X bzero(bitArray, BitArraySize);
- X t2++; count++;
- X }
- X *t2 = NULL;
- X
- X t1 = HashTable;
- X t2 = newTable;
- X tm = mergeTable = (struct idname **)calloc(HashFill + count + 1, sizeof(struct idname *));
- X while (*t1 && *t2) {
- X cmp = strcmp((*t1)->idn_name, (*t2)->idn_name);
- X if (cmp < 0)
- X *tm++ = *t1++;
- X else if (cmp > 0)
- X *tm++ = *t2++;
- X else {
- X (*t1)->idn_flags |= (*t2)->idn_flags;
- X (*t1)->idn_flags &= ~IDN_SOLO;
- X bitsset((*t1)->idn_bitv, (*t2)->idn_bitv, BitArraySize);
- X *tm++ = *t1;
- X t1++, t2++;
- X }
- X }
- X while (*t1)
- X *tm++ = *t1++;
- X while (*t2)
- X *tm++ = *t2++;
- X *tm = NULL;
- X HashTable = mergeTable;
- X HashFill = tm - mergeTable;
- X}
- X
- X/*
- X Cons up a list of idArgs as supplied in a file.
- X*/
- Xvoid
- XfileIdArgs(argFILE, idArgsP)
- X FILE *argFILE;
- X struct idarg **idArgsP;
- X{
- X int fileCount;
- X char buf[BUFSIZ];
- X char *arg;
- X
- X fileCount = 0;
- X while (fgets(buf, sizeof(buf), argFILE)) {
- X (*idArgsP)->ida_arg = arg = strnsav(buf, strlen(buf)-1);
- X if (*arg == '+' || *arg == '-') {
- X (*idArgsP)->ida_flags = IDA_ARG;
- X (*idArgsP)->ida_index = -1;
- X } else {
- X (*idArgsP)->ida_flags = IDA_SCAN|IDA_PATH;
- X (*idArgsP)->ida_index = postIncr(&PathCount);
- X ScanCount++;
- X }
- X (*idArgsP) = ((*idArgsP)->ida_next = NEW(struct idarg));
- X }
- X}
- X
- Xvoid
- XinitHashTable(pathCount)
- X int pathCount;
- X{
- X if ((HashSize = round2((pathCount << 6) + 511)) > 0x8000)
- X HashSize = 0x8000;
- X HashMaxLoad = HashSize - (HashSize >> 4); /* about 94% */
- X HashTable = (struct idname **)calloc(HashSize, sizeof(struct idname *));
- X}
- X
- X/*
- X Double the size of the hash table in the
- X event of overflow...
- X*/
- Xvoid
- Xrehash()
- X{
- X long oldHashSize = HashSize;
- X struct idname **oldHashTable = HashTable;
- X register struct idname **htp;
- X register struct idname **slot;
- X
- X HashSize *= 2;
- X if (Verbose)
- X fprintf(stderr, "Rehashing... (doubling size to %ld)\n", HashSize);
- X HashMaxLoad = HashSize - (HashSize >> 4);
- X HashTable = (struct idname **)calloc(HashSize, sizeof(struct idname *));
- X
- X HashFill = 0;
- X for (htp = oldHashTable; htp < &oldHashTable[oldHashSize]; htp++) {
- X if (*htp == NULL)
- X continue;
- X slot = (struct idname **)hashSearch((*htp)->idn_name, (char *)HashTable, HashSize, sizeof(struct idname *), h1str, h2str, idnHashCmp, &HashProbes);
- X if (*slot) {
- X fprintf(stderr, "%s: Duplicate hash entry!\n");
- X exit(1);
- X }
- X *slot = *htp;
- X HashSearches++;
- X HashFill++;
- X }
- X free(oldHashTable);
- X}
- X
- X/*
- X Round a given number up to the nearest power of 2.
- X*/
- Xint
- Xround2(rough)
- X int rough;
- X{
- X int round;
- X
- X round = 1;
- X while (rough) {
- X round <<= 1;
- X rough >>= 1;
- X }
- X return round;
- X}
- X
- X/*
- X `compar' function for hashSearch()
- X*/
- Xint
- XidnHashCmp(key, idn)
- X char *key;
- X struct idname **idn;
- X{
- X int collate;
- X
- X if (*idn == NULL)
- X return 0;
- X
- X if ((collate = strcmp(key, (*idn)->idn_name)) == 0)
- X (*idn)->idn_flags &= ~IDN_SOLO; /* we found another occurance */
- X
- X return collate;
- X}
- X
- X/*
- X `compar' function for qsort().
- X*/
- Xint
- XidnQsortCmp(idn1, idn2)
- X struct idname **idn1;
- X struct idname **idn2;
- X{
- X if (*idn1 == *idn2)
- X return 0;
- X if (*idn1 == NULL)
- X return 1;
- X if (*idn2 == NULL)
- X return -1;
- X
- X return strcmp((*idn1)->idn_name, (*idn2)->idn_name);
- X}
- X
- X/*
- X Allocate a new idname struct and fill in the name field.
- X We allocate memory in large chunks to avoid frequent
- X calls to malloc() which is a major pig.
- X*/
- Xstruct idname *
- XnewIdName(name)
- X char *name;
- X{
- X register struct idname *idn;
- X register char *allocp;
- X register int allocsiz;
- X static char *allocBuf = NULL;
- X static char *allocEnd = NULL;
- X#define ALLOCSIZ (8*1024)
- X
- X allocsiz = sizeof(struct idname) + strlen(name) + 1 + BitArraySize;
- X allocsiz += (sizeof(long) - 1);
- X allocsiz &= ~(sizeof(long) - 1);
- X
- X allocp = allocBuf;
- X allocBuf += allocsiz;
- X if (allocBuf > allocEnd) {
- X allocBuf = malloc(ALLOCSIZ);
- X allocEnd = &allocBuf[ALLOCSIZ];
- X allocp = allocBuf;
- X allocBuf += allocsiz;
- X }
- X
- X idn = (struct idname *)allocp;
- X allocp += sizeof(struct idname);
- X idn->idn_bitv = allocp;
- X for (allocsiz = BitArraySize; allocsiz--; allocp++)
- X *allocp = '\0';
- X idn->idn_name = strcpy(allocp, name);
- X
- X return idn;
- X}
- X
- Xint
- XpostIncr(ip)
- X int *ip;
- X{
- X register int i;
- X int save;
- X
- X save = *ip;
- X i = save + 1;
- X if ((i & 0x00ff) == 0x00ff)
- X i++;
- X if ((i & 0xff00) == 0xff00) /* This isn't bloody likely */
- X i += 0x100;
- X *ip = i;
- X
- X return save;
- X}
- X
- X/*
- X Move all non-NULL table entries to the front of the table.
- X return the number of non-NULL elements in the table.
- X*/
- Xint
- XhashCompress(table, size)
- X char **table;
- X int size;
- X{
- X register char **front;
- X register char **back;
- X
- X front = &table[-1];
- X back = &table[size];
- X
- X for (;;) {
- X while (*--back == NULL)
- X ;
- X if (back < front)
- X break;
- X while (*++front != NULL)
- X ;
- X if (back < front)
- X break;
- X *front = *back;
- X }
- X
- X return (back - table + 1);
- X}
- SHAR_EOF
- if test 17095 -ne "`wc -c < 'mkid.c'`"
- then
- echo shar: error transmitting "'mkid.c'" '(should have been 17095 characters)'
- fi
- echo shar: extracting "'numtst.c'" '(60 characters)'
- sed 's/^X//' << \SHAR_EOF > 'numtst.c'
- X000004
- X00010
- X012
- X020
- X04
- X0x00004
- X0x00010
- X0x00a
- X0XA
- X10
- X16
- X4
- X8
- SHAR_EOF
- if test 60 -ne "`wc -c < 'numtst.c'`"
- then
- echo shar: error transmitting "'numtst.c'" '(should have been 60 characters)'
- fi
- echo shar: extracting "'opensrc.c'" '(2172 characters)'
- sed 's/^X//' << \SHAR_EOF > 'opensrc.c'
- X/* Copyright (c) 1986, Greg McGary */
- Xstatic char sccsid[] = "@(#)opensrc.c 1.1 86/10/09";
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- XFILE *openSrcFILE();
- Xchar *getSCCS();
- Xchar *coRCS();
- X
- XFILE *
- XopenSrcFILE(path, sccsDir, rcsDir)
- X char *path;
- X char *sccsDir;
- X char *rcsDir;
- X{
- X char *command = NULL;
- X char *what = NULL;
- X char *get = "get SCCS file";
- X char *checkout = "checkout RCS file";
- X char *dirName;
- X char *baseName;
- X FILE *srcFILE;
- X
- X if ((srcFILE = fopen(path, "r")) != NULL)
- X return srcFILE;
- X
- X if ((baseName = strrchr(path, '/')) == NULL) {
- X dirName = ".";
- X baseName = path;
- X } else {
- X dirName = path;
- X *baseName++ = '\0';
- X }
- X
- X if (rcsDir && (command = coRCS(dirName, baseName, rcsDir)))
- X what = checkout;
- X else if (sccsDir && (command = getSCCS(dirName, baseName, sccsDir)))
- X what = get;
- X else if ((command = coRCS(dirName, baseName, "RCS"))
- X || (command = coRCS(dirName, baseName, ".")))
- X what = checkout;
- X else if ((command = getSCCS(dirName, baseName, "SCCS"))
- X || (command = getSCCS(dirName, baseName, "sccs"))
- X || (command = getSCCS(dirName, baseName, ".")))
- X what = get;
- X
- X if (dirName == path)
- X *--baseName = '/';
- X
- X if (!command) {
- X filerr("open", path);
- X return NULL;
- X }
- X
- X system(command);
- X if ((srcFILE = fopen(path, "r")) == NULL) {
- X filerr("open", path);
- X return NULL;
- X }
- X
- X fprintf(stderr, "%s\n", command);
- X return srcFILE;
- X}
- X
- Xchar *
- XgetSCCS(dir, base, sccsDir)
- X char *dir;
- X char *base;
- X char *sccsDir;
- X{
- X static char cmdBuf[BUFSIZ];
- X char fileBuf[BUFSIZ];
- X struct stat statBuf;
- X
- X if (!*sccsDir)
- X sccsDir = ".";
- X
- X sprintf(fileBuf, "%s/%s/s.%s", dir, sccsDir, base);
- X if (stat(fileBuf, &statBuf) < 0)
- X return NULL;
- X sprintf(cmdBuf, "cd %s; get -s %s/s.%s", dir, sccsDir, base);
- X
- X return cmdBuf;
- X}
- X
- Xchar *
- XcoRCS(dir, base, rcsDir)
- X char *dir;
- X char *base;
- X char *rcsDir;
- X{
- X static char cmdBuf[BUFSIZ];
- X char fileBuf[BUFSIZ];
- X struct stat statBuf;
- X
- X if (!*rcsDir)
- X rcsDir = ".";
- X
- X sprintf(fileBuf, "%s/%s/%s,v", dir, rcsDir, base);
- X if (stat(fileBuf, &statBuf) < 0)
- X return NULL;
- X sprintf(cmdBuf, "cd %s; co -q %s/%s,v", dir, rcsDir, base);
- X
- X return cmdBuf;
- X}
- SHAR_EOF
- if test 2172 -ne "`wc -c < 'opensrc.c'`"
- then
- echo shar: error transmitting "'opensrc.c'" '(should have been 2172 characters)'
- fi
- echo shar: extracting "'paths.c'" '(3629 characters)'
- sed 's/^X//' << \SHAR_EOF > 'paths.c'
- X/* Copyright (c) 1986, Greg McGary */
- Xstatic char sccsid[] = "@(#)paths.c 1.1 86/10/09";
- X
- X#include <bool.h>
- X#include <stdio.h>
- X#include <string.h>
- X
- Xbool canCrunch();
- Xchar *getDirToName();
- Xchar *rootName();
- Xchar *skipJunk();
- Xchar *spanPath();
- Xchar *suffName();
- X
- Xchar *
- XspanPath(dir, arg)
- X char *dir;
- X char *arg;
- X{
- X static char pathBuf[BUFSIZ];
- X char *path;
- X char *argTail;
- X char *dirTail;
- X int argLength;
- X int dirLength;
- X
- X for (dirTail = &dir[strlen(dir)-1]; *dirTail == '/'; dirTail--)
- X *dirTail = '\0';
- X for (;;) {
- X dir = skipJunk(dir);
- X if ((dirTail = strchr(dir, '/')) == NULL)
- X dirTail = &dir[strlen(dir)];
- X dirLength = dirTail - dir;
- X
- X arg = skipJunk(arg);
- X if ((argTail = strchr(arg, '/')) == NULL)
- X break;
- X argLength = argTail - arg;
- X
- X if (argLength != dirLength)
- X break;
- X if (!strnequ(arg, dir, argLength))
- X break;
- X arg = argTail;
- X dir = dirTail;
- X }
- X
- X (path = pathBuf)[0] = '\0';
- X for (; dir && *dir; dir = skipJunk(strchr(dir, '/'))) {
- X strcpy(path, "../");
- X path += 3;
- X }
- X strcat(path, arg);
- X return pathBuf;
- X}
- X
- Xchar *
- XskipJunk(path)
- X char *path;
- X{
- X if (path == NULL)
- X return NULL;
- X while (*path == '/')
- X path++;
- X while (path[0] == '.' && path[1] == '/') {
- X path += 2;
- X while (*path == '/')
- X path++;
- X }
- X if (strequ(path, "."))
- X path++;
- X
- X return path;
- X}
- X
- Xchar *
- XrootName(path)
- X char *path;
- X{
- X static char pathBuf[BUFSIZ];
- X char *root;
- X char *dot;
- X
- X if ((root = strrchr(path, '/')) == NULL)
- X root = path;
- X else
- X root++;
- X
- X if ((dot = strrchr(root, '.')) == NULL)
- X strcpy(pathBuf, root);
- X else {
- X strncpy(pathBuf, root, dot - root);
- X pathBuf[dot - root] = '\0';
- X }
- X return pathBuf;
- X}
- X
- Xchar *
- XsuffName(path)
- X char *path;
- X{
- X char *dot;
- X
- X if ((dot = strrchr(path, '.')) == NULL)
- X return "";
- X return dot;
- X}
- X
- Xbool
- XcanCrunch(path1, path2)
- X char *path1;
- X char *path2;
- X{
- X char *slash1;
- X char *slash2;
- X
- X slash1 = strrchr(path1, '/');
- X slash2 = strrchr(path2, '/');
- X
- X if (slash1 == NULL && slash2 == NULL)
- X return strequ(suffName(path1), suffName(path2));
- X if ((slash1 - path1) != (slash2 - path2))
- X return FALSE;
- X if (!strnequ(path1, path2, slash1 - path1))
- X return FALSE;
- X return strequ(suffName(slash1), suffName(slash2));
- X}
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#ifdef NDIR
- X#include <ndir.h>
- X#else
- X#include <sys/dir.h>
- X#endif
- X
- Xstatic char dot[] = ".";
- Xstatic char dotdot[] = "..";
- X
- X/*
- X Return our directory name relative to the first parent dir
- X that contains a file with a name that matches `topName'.
- X Fail if we hit the root, or if any dir in our way is unreadable.
- X*/
- Xchar *
- XgetDirToName(topName)
- X char *topName;
- X{
- X register struct direct *dirp;
- X register DIR *dirdp;
- X static char nameBuf[BUFSIZ];
- X char *name;
- X struct stat dStat;
- X struct stat ddStat;
- X
- X name = &nameBuf[sizeof(nameBuf)-1];
- X *name = '\0';
- X for (;;) {
- X if (stat(topName, &dStat) == 0) {
- X if (!*name)
- X name = dot;
- X else
- X chdir(name);
- X return name;
- X } if (stat(dot, &dStat) < 0)
- X return NULL;
- X if ((dirdp = opendir(dotdot)) == NULL)
- X return NULL;
- X if (fstat(dirdp->dd_fd, &ddStat) < 0)
- X return NULL;
- X if (chdir(dotdot) < 0)
- X return NULL;
- X if (dStat.st_dev == ddStat.st_dev) {
- X if (dStat.st_ino == ddStat.st_ino)
- X return NULL;
- X do {
- X if ((dirp = readdir(dirdp)) == NULL)
- X return NULL;
- X } while (dirp->d_ino != dStat.st_ino);
- X } else {
- X do {
- X if ((dirp = readdir(dirdp)) == NULL)
- X return NULL;
- X stat(dirp->d_name, &ddStat);
- X } while (ddStat.st_ino != dStat.st_ino || ddStat.st_dev != dStat.st_dev);
- X }
- X closedir(dirdp);
- X
- X if (*name != '\0')
- X *--name = '/';
- X name -= dirp->d_namlen;
- X strncpy(name, dirp->d_name, dirp->d_namlen);
- X }
- X}
- SHAR_EOF
- if test 3629 -ne "`wc -c < 'paths.c'`"
- then
- echo shar: error transmitting "'paths.c'" '(should have been 3629 characters)'
- fi
- echo shar: extracting "'scan-asm.c'" '(6157 characters)'
- sed 's/^X//' << \SHAR_EOF > 'scan-asm.c'
- X/* Copyright (c) 1986, Greg McGary */
- Xstatic char sccsid[] = "@(#)scan-asm.c 1.2 86/11/06";
- X
- X#include <bool.h>
- X#include <stdio.h>
- X#include <string.h>
- X#include <ctype.h>
- X#include <id.h>
- X
- Xchar *getAsmId();
- Xvoid setAsmArgs();
- X
- Xstatic void clrCtype();
- Xstatic void setCtype();
- X
- X#define I1 0x01 /* 1st char of an identifier [a-zA-Z_] */
- X#define NM 0x02 /* digit [0-9a-fA-FxX] */
- X#define NL 0x04 /* newline: \n */
- X#define CM 0x08 /* assembler comment char: usually # or | */
- X#define IG 0x10 /* ignore `identifiers' with these chars in them */
- X#define C1 0x20 /* C comment introduction char: / */
- X#define C2 0x40 /* C comment termination char: * */
- X#define EF 0x80 /* EOF */
- X
- X/* Assembly Language character classes */
- X#define ISID1ST(c) ((rct)[c]&(I1))
- X#define ISIDREST(c) ((rct)[c]&(I1|NM))
- X#define ISNUMBER(c) ((rct)[c]&(NM))
- X#define ISEOF(c) ((rct)[c]&(EF))
- X#define ISCOMMENT(c) ((rct)[c]&(CM))
- X#define ISBORING(c) (!((rct)[c]&(EF|NL|I1|NM|CM|C1)))
- X#define ISCBORING(c) (!((rct)[c]&(EF|NL)))
- X#define ISCCBORING(c) (!((rct)[c]&(EF|C2)))
- X#define ISIGNORE(c) ((rct)[c]&(IG))
- X
- Xstatic char idctype[] = {
- X
- X EF,
- X
- X /* 0 1 2 3 4 5 6 7 */
- X /* ----- ----- ----- ----- ----- ----- ----- ----- */
- X
- X /*000*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*010*/ 0, 0, NL, 0, 0, 0, 0, 0,
- X /*020*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*030*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*040*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*050*/ 0, 0, C2, 0, 0, 0, 0, C1,
- X /*060*/ NM, NM, NM, NM, NM, NM, NM, NM,
- X /*070*/ NM, NM, 0, 0, 0, 0, 0, 0,
- X /*100*/ 0, I1|NM, I1|NM, I1|NM, I1|NM, I1|NM, I1|NM, I1,
- X /*110*/ I1, I1, I1, I1, I1|NM, I1, I1, I1,
- X /*120*/ I1, I1, I1, I1, I1, I1, I1, I1,
- X /*130*/ I1|NM, I1, I1, 0, 0, 0, 0, I1,
- X /*140*/ 0, I1|NM, I1|NM, I1|NM, I1|NM, I1|NM, I1|NM, I1,
- X /*150*/ I1, I1, I1, I1, I1|NM, I1, I1, I1,
- X /*160*/ I1, I1, I1, I1, I1, I1, I1, I1,
- X /*170*/ I1|NM, I1, I1, 0, 0, 0, 0, 0,
- X
- X /*200*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*210*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*220*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*230*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*240*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*250*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*260*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*270*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*300*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*310*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*320*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*330*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*340*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*350*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*360*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*370*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X
- X};
- X
- Xstatic bool eatUnder = TRUE;
- Xstatic bool preProcess = TRUE;
- X
- X/*
- X Grab the next identifier the assembly language
- X source file opened with the handle `inFILE'.
- X This state machine is built for speed, not elegance.
- X*/
- Xchar *
- XgetAsmId(inFILE, flagP)
- X FILE *inFILE;
- X int *flagP;
- X{
- X static char idBuf[BUFSIZ];
- X register char *rct = &idctype[1];
- X register int c;
- X register char *id = idBuf;
- X static bool newLine = TRUE;
- X
- Xtop:
- X c = getc(inFILE);
- X if (preProcess > 0 && newLine) {
- X newLine = FALSE;
- X if (c != '#')
- X goto next;
- X while (ISBORING(c))
- X c = getc(inFILE);
- X if (!ISID1ST(c))
- X goto next;
- X id = idBuf;
- X *id++ = c;
- X while (ISIDREST(c = getc(inFILE)))
- X *id++ = c;
- X *id = '\0';
- X if (strequ(idBuf, "include")) {
- X while (c != '"' && c != '<')
- X c = getc(inFILE);
- X id = idBuf;
- X *id++ = c = getc(inFILE);
- X while ((c = getc(inFILE)) != '"' && c != '>')
- X *id++ = c;
- X *id = '\0';
- X *flagP = IDN_STRING;
- X return idBuf;
- X }
- X if (strnequ(idBuf, "if", 2)
- X || strequ(idBuf, "define")
- X || strequ(idBuf, "undef"))
- X goto next;
- X while (c != '\n')
- X c = getc(inFILE);
- X newLine = TRUE;
- X goto top;
- X }
- X
- Xnext:
- X while (ISBORING(c))
- X c = getc(inFILE);
- X
- X if (ISCOMMENT(c)) {
- X while (ISCBORING(c))
- X c = getc(inFILE);
- X newLine = TRUE;
- X }
- X
- X if (ISEOF(c)) {
- X newLine = TRUE;
- X return NULL;
- X }
- X
- X if (c == '\n') {
- X newLine = TRUE;
- X goto top;
- X }
- X
- X if (c == '/') {
- X if ((c = getc(inFILE)) != '*')
- X goto next;
- X c = getc(inFILE);
- X for (;;) {
- X while (ISCCBORING(c))
- X c = getc(inFILE);
- X if ((c = getc(inFILE)) == '/') {
- X c = getc(inFILE);
- X break;
- X } else if (ISEOF(c)) {
- X newLine = TRUE;
- X return NULL;
- X }
- X }
- X goto next;
- X }
- X
- X id = idBuf;
- X if (eatUnder && c == '_' && !ISID1ST(c = getc(inFILE))) {
- X ungetc(c, inFILE);
- X return "_";
- X }
- X *id++ = c;
- X if (ISID1ST(c)) {
- X *flagP = IDN_NAME;
- X while (ISIDREST(c = getc(inFILE)))
- X *id++ = c;
- X } else if (ISNUMBER(c)) {
- X *flagP = IDN_NUMBER;
- X while (ISNUMBER(c = getc(inFILE)))
- X *id++ = c;
- X } else {
- X if (isprint(c))
- X fprintf(stderr, "junk: `%c'", c);
- X else
- X fprintf(stderr, "junk: `\\%03o'", c);
- X goto next;
- X }
- X
- X *id = '\0';
- X for (id = idBuf; *id; id++)
- X if (ISIGNORE(*id))
- X goto next;
- X ungetc(c, inFILE);
- X *flagP |= IDN_LITERAL;
- X return idBuf;
- X}
- X
- Xstatic void
- XsetCtype(chars, type)
- X char *chars;
- X int type;
- X{
- X char *rct = &idctype[1];
- X
- X while (*chars)
- X rct[*chars++] |= type;
- X}
- Xstatic void
- XclrCtype(chars, type)
- X char *chars;
- X int type;
- X{
- X char *rct = &idctype[1];
- X
- X while (*chars)
- X rct[*chars++] &= ~type;
- X}
- X
- Xextern char *MyName;
- Xstatic void
- Xusage(lang)
- X char *lang;
- X{
- X fprintf(stderr, "Usage: %s -S%s([-c<cc>] [-u] [(+|-)a<cc>] [(+|-)p] [(+|-)C])\n", MyName, lang);
- X exit(1);
- X}
- Xstatic char *asmDocument[] =
- X{
- X"The Assembler scanner arguments take the form -Sasm<arg>, where",
- X"<arg> is one of the following: (<cc> denotes one or more characters)",
- X" -c<cc> . . . . <cc> introduce(s) a comment until end-of-line.",
- X" (+|-)u . . . . (Do|Don't) strip a leading `_' from ids.",
- X" (+|-)a<cc> . . Allow <cc> in ids, and (keep|ignore) those ids.",
- X" (+|-)p . . . . (Do|Don't) handle C-preprocessor directives.",
- X" (+|-)C . . . . (Do|Don't) handle C-style comments. (/* */)",
- XNULL
- X};
- Xvoid
- XsetAsmArgs(lang, op, arg)
- X char *lang;
- X int op;
- X char *arg;
- X{
- X if (op == '?') {
- X document(asmDocument);
- X return;
- X }
- X switch (*arg++)
- X {
- X case 'a':
- X setCtype(arg, I1|((op == '-') ? IG : 0));
- X break;
- X case 'c':
- X setCtype(arg, CM);
- X break;
- X case 'u':
- X eatUnder = (op == '+');
- X break;
- X case 'p':
- X preProcess = (op == '+');
- X break;
- X case 'C':
- X if (op == '+') {
- X setCtype("/", C1);
- X setCtype("*", C2);
- X } else {
- X clrCtype("/", C1);
- X clrCtype("*", C2);
- X }
- X break;
- X default:
- X if (lang)
- X usage(lang);
- X break;
- X }
- X}
- SHAR_EOF
- if test 6157 -ne "`wc -c < 'scan-asm.c'`"
- then
- echo shar: error transmitting "'scan-asm.c'" '(should have been 6157 characters)'
- fi
- echo shar: extracting "'scan-c.c'" '(6502 characters)'
- sed 's/^X//' << \SHAR_EOF > 'scan-c.c'
- X/* Copyright (c) 1986, Greg McGary */
- Xstatic char sccsid[] = "@(#)scan-c.c 1.1 86/10/09";
- X
- X#include <bool.h>
- X#include <stdio.h>
- X#include <string.h>
- X#include <id.h>
- X
- Xchar *getCId();
- Xvoid setCArgs();
- X
- Xstatic void clrCtype();
- Xstatic void setCtype();
- X
- X#define I1 0x0001 /* 1st char of an identifier [a-zA-Z_] */
- X#define DG 0x0002 /* decimal digit [0-9] */
- X#define NM 0x0004 /* extra chars in a hex or long number [a-fA-FxXlL] */
- X#define C1 0x0008 /* C comment introduction char: / */
- X#define C2 0x0010 /* C comment termination char: * */
- X#define Q1 0x0020 /* single quote: ' */
- X#define Q2 0x0040 /* double quote: " */
- X#define ES 0x0080 /* escape char: \ */
- X#define NL 0x0100 /* newline: \n */
- X#define EF 0x0200 /* EOF */
- X#define SK 0x0400 /* Make these chars valid for names within strings */
- X
- X/*
- X character class membership macros:
- X*/
- X#define ISDIGIT(c) ((rct)[c]&(DG)) /* digit */
- X#define ISNUMBER(c) ((rct)[c]&(DG|NM)) /* legal in a number */
- X#define ISEOF(c) ((rct)[c]&(EF)) /* EOF */
- X#define ISID1ST(c) ((rct)[c]&(I1)) /* 1st char of an identifier */
- X#define ISIDREST(c) ((rct)[c]&(I1|DG)) /* rest of an identifier */
- X#define ISSTRKEEP(c) ((rct)[c]&(I1|DG|SK)) /* keep contents of string */
- X/*
- X The `BORING' classes should be skipped over
- X until something interesting comes along...
- X*/
- X#define ISBORING(c) (!((rct)[c]&(EF|NL|I1|DG|Q1|Q2|C1))) /* fluff */
- X#define ISCBORING(c) (!((rct)[c]&(EF|C2))) /* comment fluff */
- X#define ISQ1BORING(c) (!((rct)[c]&(EF|NL|Q1|ES))) /* char const fluff */
- X#define ISQ2BORING(c) (!((rct)[c]&(EF|NL|Q2|ES))) /* quoted str fluff */
- X
- Xstatic short idctype[] = {
- X
- X EF,
- X
- X /* 0 1 2 3 4 5 6 7 */
- X /* ----- ----- ----- ----- ----- ----- ----- ----- */
- X
- X /*000*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*010*/ 0, 0, NL, 0, 0, 0, 0, 0,
- X /*020*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*030*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*040*/ 0, 0, Q2, 0, 0, 0, 0, Q1,
- X /*050*/ 0, 0, C2, 0, 0, 0, 0, C1,
- X /*060*/ DG, DG, DG, DG, DG, DG, DG, DG,
- X /*070*/ DG, DG, 0, 0, 0, 0, 0, 0,
- X /*100*/ 0, I1|NM, I1|NM, I1|NM, I1|NM, I1|NM, I1|NM, I1,
- X /*110*/ I1, I1, I1, I1, I1|NM, I1, I1, I1,
- X /*120*/ I1, I1, I1, I1, I1, I1, I1, I1,
- X /*130*/ I1|NM, I1, I1, 0, ES, 0, 0, I1,
- X /*140*/ 0, I1|NM, I1|NM, I1|NM, I1|NM, I1|NM, I1|NM, I1,
- X /*150*/ I1, I1, I1, I1, I1|NM, I1, I1, I1,
- X /*160*/ I1, I1, I1, I1, I1, I1, I1, I1,
- X /*170*/ I1|NM, I1, I1, 0, 0, 0, 0, 0,
- X
- X /*200*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*210*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*220*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*230*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*240*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*250*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*260*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*270*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*300*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*310*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*320*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*330*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*340*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*350*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*360*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X /*370*/ 0, 0, 0, 0, 0, 0, 0, 0,
- X
- X};
- X
- Xstatic bool eatUnder = TRUE;
- X
- X/*
- X Grab the next identifier the C source
- X file opened with the handle `inFILE'.
- X This state machine is built for speed, not elegance.
- X*/
- Xchar *
- XgetCId(inFILE, flagP)
- X FILE *inFILE;
- X int *flagP;
- X{
- X static char idBuf[BUFSIZ];
- X static bool newLine = TRUE;
- X register short *rct = &idctype[1];
- X register int c;
- X register char *id = idBuf;
- X
- Xtop:
- X c = getc(inFILE);
- X if (newLine) {
- X newLine = FALSE;
- X if (c != '#')
- X goto next;
- X while (ISBORING(c))
- X c = getc(inFILE);
- X if (!ISID1ST(c))
- X goto next;
- X id = idBuf;
- X *id++ = c;
- X while (ISIDREST(c = getc(inFILE)))
- X *id++ = c;
- X *id = '\0';
- X if (strequ(idBuf, "include")) {
- X while (c != '"' && c != '<')
- X c = getc(inFILE);
- X id = idBuf;
- X *id++ = c = getc(inFILE);
- X while ((c = getc(inFILE)) != '"' && c != '>')
- X *id++ = c;
- X *id = '\0';
- X *flagP = IDN_STRING;
- X return idBuf;
- X }
- X if (strnequ(idBuf, "if", 2)
- X || strequ(idBuf, "define")
- X || strequ(idBuf, "undef"))
- X goto next;
- X while (c != '\n')
- X c = getc(inFILE);
- X newLine = TRUE;
- X goto top;
- X }
- X
- Xnext:
- X while (ISBORING(c))
- X c = getc(inFILE);
- X
- X switch (c)
- X {
- X case '"':
- X id = idBuf;
- X *id++ = c = getc(inFILE);
- X for (;;) {
- X while (ISQ2BORING(c))
- X *id++ = c = getc(inFILE);
- X if (c == '\\') {
- X *id++ = c = getc(inFILE);
- X continue;
- X } else if (c != '"')
- X goto next;
- X break;
- X }
- X *--id = '\0';
- X id = idBuf;
- X while (ISSTRKEEP(*id))
- X id++;
- X if (*id || id == idBuf) {
- X c = getc(inFILE);
- X goto next;
- X }
- X *flagP = IDN_STRING;
- X if (eatUnder && idBuf[0] == '_' && idBuf[1])
- X return &idBuf[1];
- X else
- X return idBuf;
- X
- X case '\'':
- X c = getc(inFILE);
- X for (;;) {
- X while (ISQ1BORING(c))
- X c = getc(inFILE);
- X if (c == '\\') {
- X c = getc(inFILE);
- X continue;
- X } else if (c == '\'')
- X c = getc(inFILE);
- X goto next;
- X }
- X
- X case '/':
- X if ((c = getc(inFILE)) != '*')
- X goto next;
- X c = getc(inFILE);
- X for (;;) {
- X while (ISCBORING(c))
- X c = getc(inFILE);
- X if ((c = getc(inFILE)) == '/') {
- X c = getc(inFILE);
- X goto next;
- X } else if (ISEOF(c)) {
- X newLine = TRUE;
- X return NULL;
- X }
- X }
- X
- X case '\n':
- X newLine = TRUE;
- X goto top;
- X
- X default:
- X if (ISEOF(c)) {
- X newLine = TRUE;
- X return NULL;
- X }
- X name:
- X id = idBuf;
- X *id++ = c;
- X if (ISID1ST(c)) {
- X *flagP = IDN_NAME;
- X while (ISIDREST(c = getc(inFILE)))
- X *id++ = c;
- X } else if (ISDIGIT(c)) {
- X *flagP = IDN_NUMBER;
- X while (ISNUMBER(c = getc(inFILE)))
- X *id++ = c;
- X } else
- X fprintf(stderr, "junk: `\\%3o'", c);
- X ungetc(c, inFILE);
- X *id = '\0';
- X *flagP |= IDN_LITERAL;
- X return idBuf;
- X }
- X}
- X
- Xstatic void
- XsetCtype(chars, type)
- X char *chars;
- X int type;
- X{
- X short *rct = &idctype[1];
- X
- X while (*chars)
- X rct[*chars++] |= type;
- X}
- Xstatic void
- XclrCtype(chars, type)
- X char *chars;
- X int type;
- X{
- X short *rct = &idctype[1];
- X
- X while (*chars)
- X rct[*chars++] &= ~type;
- X}
- X
- Xextern char *MyName;
- Xstatic void
- Xusage(lang)
- X char *lang;
- X{
- X fprintf(stderr, "Usage: %s does not accept %s scanner arguments\n", MyName, lang);
- X exit(1);
- X}
- Xstatic char *cDocument[] =
- X{
- X"The C scanner arguments take the form -Sc<arg>, where <arg>",
- X"is one of the following: (<cc> denotes one or more characters)",
- X" (+|-)u . . . . (Do|Don't) strip a leading `_' from ids in strings.",
- X" -s<cc> . . . . Allow <cc> in string ids.",
- XNULL
- X};
- Xvoid
- XsetCArgs(lang, op, arg)
- X char *lang;
- X int op;
- X char *arg;
- X{
- X if (op == '?') {
- X document(cDocument);
- X return;
- X }
- X switch (*arg++)
- X {
- X case 'u':
- X eatUnder = (op == '+');
- X break;
- X case 's':
- X setCtype(arg, SK);
- X break;
- X default:
- X if (lang)
- X usage(lang);
- X break;
- X }
- X}
- SHAR_EOF
- if test 6502 -ne "`wc -c < 'scan-c.c'`"
- then
- echo shar: error transmitting "'scan-c.c'" '(should have been 6502 characters)'
- fi
- echo shar: extracting "'stoi.c'" '(1883 characters)'
- sed 's/^X//' << \SHAR_EOF > 'stoi.c'
- X/* Copyright (c) 1986, Greg McGary */
- Xstatic char sccsid[] = "@(#)stoi.c 1.1 86/10/09";
- X
- X#include <radix.h>
- X#include <ctype.h>
- X
- Xint dtoi();
- Xint otoi();
- Xint radix();
- Xint stoi();
- Xint xtoi();
- X
- X/*
- X Use the C lexical rules to determine an ascii number's radix.
- X The radix is returned as a bit map, so that more than one radix
- X may apply. In particular, it is impossible to determine the
- X radix of 0, so return all possibilities.
- X*/
- Xint
- Xradix(name)
- X register char *name;
- X{
- X if (!isdigit(*name))
- X return 0;
- X if (*name != '0')
- X return RADIX_DEC;
- X name++;
- X if (*name == 'x' || *name == 'X')
- X return RADIX_HEX;
- X while (*name && *name == '0')
- X name++;
- X return (RADIX_OCT | ((*name)?0:RADIX_DEC));
- X}
- X
- X/*
- X Convert an ascii string number to an integer.
- X Determine the radix before converting.
- X*/
- Xint
- Xstoi(name)
- X char *name;
- X{
- X switch (radix(name))
- X {
- X case RADIX_DEC: return(dtoi(name));
- X case RADIX_OCT: return(otoi(&name[1]));
- X case RADIX_HEX: return(xtoi(&name[2]));
- X case RADIX_DEC|RADIX_OCT: return(0);
- X default: return(-1);
- X }
- X}
- X
- X/*
- X Convert an ascii octal number to an integer.
- X*/
- Xint
- Xotoi(name)
- X char *name;
- X{
- X register int n = 0;
- X
- X while (*name >= '0' && *name <= '7') {
- X n *= 010;
- X n += *name++ - '0';
- X }
- X if (*name == 'l' || *name == 'L')
- X name++;
- X return (*name ? -1 : n);
- X}
- X
- X/*
- X Convert an ascii decimal number to an integer.
- X*/
- Xint
- Xdtoi(name)
- X char *name;
- X{
- X register int n = 0;
- X
- X while (isdigit(*name)) {
- X n *= 10;
- X n += *name++ - '0';
- X }
- X if (*name == 'l' || *name == 'L')
- X name++;
- X return (*name ? -1 : n);
- X}
- X
- X/*
- X Convert an ascii hex number to an integer.
- X*/
- Xint
- Xxtoi(name)
- X char *name;
- X{
- X register int n = 0;
- X
- X while (isxdigit(*name)) {
- X n *= 0x10;
- X if (isdigit(*name))
- X n += *name++ - '0';
- X else if (islower(*name))
- X n += 0xa + *name++ - 'a';
- X else
- X n += 0xA + *name++ - 'A';
- X }
- X if (*name == 'l' || *name == 'L')
- X name++;
- X return (*name ? -1 : n);
- X}
- SHAR_EOF
- if test 1883 -ne "`wc -c < 'stoi.c'`"
- then
- echo shar: error transmitting "'stoi.c'" '(should have been 1883 characters)'
- fi
- echo shar: extracting "'tty.c'" '(1114 characters)'
- sed 's/^X//' << \SHAR_EOF > 'tty.c'
- X#ifdef TERMIO
- X#include <sys/termio.h>
- X
- Xstruct termio linemode, charmode, savemode;
- X
- Xsavetty()
- X{
- X ioctl(0, TCGETA, &savemode);
- X charmode = linemode = savemode;
- X
- X charmode.c_lflag &= ~(ECHO|ICANON|ISIG);
- X charmode.c_cc[VMIN] = 1;
- X charmode.c_cc[VTIME] = 0;
- X
- X linemode.c_lflag |= (ECHO|ICANON|ISIG);
- X linemode.c_cc[VEOF] = 'd'&037;
- X linemode.c_cc[VEOL] = 0377;
- X}
- X
- Xrestoretty()
- X{
- X ioctl(0, TCSETA, &savemode);
- X}
- X
- Xlinetty()
- X{
- X ioctl(0, TCSETA, &linemode);
- X}
- X
- Xchartty()
- X{
- X ioctl(0, TCSETA, &charmode);
- X}
- X
- X#else
- X#include <sgtty.h>
- X
- Xstruct sgttyb linemode, charmode, savemode;
- X
- Xsavetty()
- X{
- X#ifdef TIOCGETP
- X ioctl(0, TIOCGETP, &savemode);
- X#else
- X gtty(0, &savemode);
- X#endif
- X charmode = linemode = savemode;
- X
- X charmode.sg_flags &= ~ECHO;
- X charmode.sg_flags |= RAW;
- X
- X linemode.sg_flags |= ECHO;
- X linemode.sg_flags &= ~RAW;
- X}
- X
- Xrestoretty()
- X{
- X#ifdef TIOCSETP
- X ioctl(0, TIOCSETP, &savemode);
- X#else
- X stty(0, &savemode);
- X#endif
- X}
- X
- Xlinetty()
- X{
- X#ifdef TIOCSETP
- X ioctl(0, TIOCSETP, &linemode);
- X#else
- X stty(0, &savemode);
- X#endif
- X}
- X
- Xchartty()
- X{
- X#ifdef TIOCSETP
- X ioctl(0, TIOCSETP, &charmode);
- X#else
- X stty(0, &savemode);
- X#endif
- X}
- X#endif
- SHAR_EOF
- if test 1114 -ne "`wc -c < 'tty.c'`"
- then
- echo shar: error transmitting "'tty.c'" '(should have been 1114 characters)'
- fi
- echo shar: extracting "'uerror.c'" '(586 characters)'
- sed 's/^X//' << \SHAR_EOF > 'uerror.c'
- X/* Copyright (c) 1986, Greg McGary */
- Xstatic char sccsid[] = "@(#)uerror.c 1.1 86/10/09";
- X
- X#include <stdio.h>
- X
- Xchar *uerror();
- Xvoid filerr();
- X
- Xextern int errno;
- Xextern int sys_nerr;
- Xextern char *sys_errlist[];
- Xextern char *MyName;
- X
- Xchar cannot[] = "%s: Cannot %s `%s' (%s)\n";
- X
- Xchar *
- Xuerror()
- X{
- X static char errbuf[10];
- X
- X if (errno == 0 || errno >= sys_nerr) {
- X sprintf(errbuf, "error %d", errno);
- X return(errbuf);
- X }
- X return(sys_errlist[errno]);
- X}
- X
- Xvoid
- Xfilerr(syscall, fileName)
- X char *syscall;
- X char *fileName;
- X{
- X fprintf(stderr, cannot, MyName, syscall, fileName, uerror());
- X}
- SHAR_EOF
- if test 586 -ne "`wc -c < 'uerror.c'`"
- then
- echo shar: error transmitting "'uerror.c'" '(should have been 586 characters)'
- fi
- echo shar: extracting "'wmatch.c'" '(830 characters)'
- sed 's/^X//' << \SHAR_EOF > 'wmatch.c'
- X/* Copyright (c) 1986, Greg McGary */
- Xstatic char sccsid[] = "@(#)wmatch.c 1.1 86/10/09";
- X
- X#include <bool.h>
- X#include <ctype.h>
- X
- Xbool wordMatch();
- X
- X/*
- X Does `name' occur in `line' delimited by non-alphanumerics??
- X*/
- Xbool
- XwordMatch(name0, line)
- X char *name0;
- X register char *line;
- X{
- X register char *name = name0;
- X#define IS_ALNUM(c) (isalnum(c) || (c) == '_')
- X
- X for (;;) {
- X /* find an initial-character match */
- X while (*line != *name) {
- X if (*line == '\n')
- X return FALSE;
- X line++;
- X }
- X /* do we have a word delimiter on the left ?? */
- X if (IS_ALNUM(line[-1])) {
- X line++;
- X continue;
- X }
- X /* march down both strings as long as we match */
- X while (*++name == *++line)
- X ;
- X /* is this the end of `name', is there a word delimiter ?? */
- X if (*name == '\0' && !IS_ALNUM(*line))
- X return TRUE;
- X name = name0;
- X }
- X}
- SHAR_EOF
- if test 830 -ne "`wc -c < 'wmatch.c'`"
- then
- echo shar: error transmitting "'wmatch.c'" '(should have been 830 characters)'
- fi
- # End of shell archive
- exit 0
-